home *** CD-ROM | disk | FTP | other *** search
/ Ian & Stuart's Australian Mac 1993 September / September 93.iso / Archives / Games / Strategy / Puzzle / GameMaster / GM Dev Kit / Rulebook Sources / Simple Talk ƒ / Simple Talk.p next >
Encoding:
Text File  |  1991-10-26  |  9.2 KB  |  479 lines  |  [TEXT/PJMM]

  1. unit SimpleTalk;
  2.  
  3. { Simple Talk © Peter Lewis, Oct 1991 }
  4. { This program and its source are Povertyware }
  5.  
  6. interface
  7.  
  8.     uses
  9.         GameTypes;
  10.  
  11.     procedure Main (var ger: gameEventRecord);
  12.  
  13. implementation
  14.  
  15.     const
  16.         my_dialog_item = 1;
  17.         row_max = 5;
  18.         col_max = 80;
  19.         width = 2;
  20.         inset = 2;
  21.         cursor = '•';
  22.         cr = chr(13);
  23.         lf = chr(10);
  24.         bs = chr(8);
  25.         del = chr(127);
  26.         enter = chr(3);
  27.         tab = chr(9);
  28.         spc = chr(32);
  29.         nul = chr(0);
  30.  
  31.     type
  32.         pieceType = (pt_None, pt_Top, pt_Bottom);
  33.         players = pt_Top..pt_Bottom;
  34.         connectionStateType = (cs_Local, cs_Remote);
  35.         linesArray = array[1..row_max] of string[col_max];
  36.         playerRecord = record
  37.                 lines: linesArray;
  38.                 row, col: integer;
  39.             end;
  40.         globalsPeek = ptr;
  41.         gameRecord = record
  42.                 globals: globalsPeek;
  43.                 player: array[players] of playerRecord;
  44.                 connectionstate: connectionStateType;
  45.                 item_rect: rect;
  46.                 mid_line: integer;
  47.                 fi: FontInfo;
  48.             end;
  49.         gamePeek = ^gameRecord;
  50.  
  51.     procedure Fail (s: str255);
  52.     begin
  53.         DebugStr(s);
  54.     end;
  55.  
  56.     procedure MyDebug (s: string; n: longint);
  57.         var
  58.             numstr: str255;
  59.     begin
  60.         NumToString(n, numstr);
  61.         DebugStr(concat(s, numstr));
  62.     end;
  63.  
  64.     procedure DrawChr (ggame: gamePeek; p: pieceType; rw, cl: integer);
  65.         var
  66.             h, v: integer;
  67.             r: rect;
  68.             cw: integer;
  69.     begin
  70.         cw := CharWidth('a');
  71.         with ggame^.item_rect, ggame^.fi do begin
  72.             v := width + inset + ascent + (ascent + descent + leading) * (rw - 1);
  73.             if p = pt_Bottom then
  74.                 v := v + ggame^.mid_line
  75.             else
  76.                 v := v + top;
  77.             h := left + width + inset + cw * (cl - 1);
  78.             r.left := h;
  79.             r.right := h + cw;
  80.             r.top := v - ascent;
  81.             r.bottom := v + descent;
  82.             MoveTo(h, v);
  83.             EraseRect(r);
  84.             DrawChar(ggame^.player[p].lines[rw][cl]);
  85.         end;
  86.     end;
  87.  
  88.     procedure DrawLine (ggame: gamePeek; p: pieceType; rw: integer);
  89.         var
  90.             h, v: integer;
  91.             r: rect;
  92.     begin
  93.         with ggame^.item_rect, ggame^.fi do begin
  94.             v := width + inset + ascent + (ascent + descent + leading) * (rw - 1);
  95.             if p = pt_Bottom then
  96.                 v := v + ggame^.mid_line
  97.             else
  98.                 v := v + top;
  99.             h := left + width + inset;
  100.             r.left := left + width;
  101.             r.right := right - inset;
  102.             r.top := v - ascent;
  103.             r.bottom := v + descent;
  104.             MoveTo(h, v);
  105.             EraseRect(r);
  106.             DrawString(ggame^.player[p].lines[rw]);
  107.         end;
  108.     end;
  109.  
  110.     procedure DrawGame (wp: windowPtr; item: integer);
  111.         var
  112.             ggame: gamePeek;
  113.             p: pieceType;
  114.             r: integer;
  115.             h: handle;
  116.     begin
  117.         h := handle(GetWRefCon(wp));
  118.         HLock(h);
  119.         ggame := gamePeek(h^);
  120.         PenSize(width, width);
  121.         FrameRect(ggame^.item_rect);
  122.         with ggame^, item_rect do begin
  123.             MoveTo(left, mid_line);
  124.             LineTo(right - width, mid_line);
  125.         end;
  126.         PenNormal;
  127.         for p := pt_Top to pt_Bottom do
  128.             for r := 1 to row_max do
  129.                 DrawLine(ggame, p, r);
  130.         HUnlock(h);
  131.     end;
  132.  
  133.     procedure Main (var ger: gameEventRecord);
  134.         var
  135.             gglobals: globalsPeek;
  136.             ggame: gamePeek;
  137.             gwindow: windowPtr;
  138.             ghandle: handle;
  139.  
  140.         procedure SetMyTurn;
  141.         begin
  142.             ger.myturn := true;
  143.         end;
  144.  
  145.         procedure NextPlayer;
  146.         begin
  147.             SetMyTurn;
  148.         end;
  149.  
  150.         function CheckWin: pieceType;
  151.         begin
  152.             CheckWin := pt_None;
  153.         end;
  154.  
  155.         procedure ClearRow (p: players; r: integer);
  156.             var
  157.                 c: integer;
  158.         begin
  159.             r := (r + row_max - 1) mod row_max + 1;
  160.             for c := 1 to col_max do
  161.                 ggame^.player[p].lines[r][c] := spc;
  162.             DrawLine(ggame, p, r);
  163.         end;
  164.  
  165.         procedure DoChar (p: players; ch: char);
  166.             const
  167.                 ff = chr(255);
  168.             procedure DoCh;
  169.             begin
  170.                 with ggame^.player[p] do begin
  171.                     lines[row][col] := ch;
  172.                     DrawChr(ggame, p, row, col);
  173.                     col := col + 1;
  174.                     if col = col_max + 1 then begin
  175.                         row := row mod row_max + 1;
  176.                         ClearRow(p, row + 1);
  177.                         col := 1;
  178.                     end;
  179.                     lines[row][col] := cursor;
  180.                     DrawChr(ggame, p, row, col);
  181.                 end;
  182.             end;
  183.             procedure DoDel;
  184.             begin
  185.                 with ggame^.player[p] do begin
  186.                     lines[row][col] := spc;
  187.                     DrawChr(ggame, p, row, col);
  188.                     if col > 1 then
  189.                         col := col - 1
  190.                     else
  191.                         col := col_max;
  192.                     lines[row][col] := cursor;
  193.                     DrawChr(ggame, p, row, col);
  194.                 end;
  195.             end;
  196.             procedure DoCR;
  197.             begin
  198.                 with ggame^.player[p] do begin
  199.                     lines[row][col] := spc;
  200.                     DrawChr(ggame, p, row, col);
  201.                     row := row mod row_max + 1;
  202.                     ClearRow(p, row + 1);
  203.                     col := 1;
  204.                     lines[row][col] := cursor;
  205.                     DrawChr(ggame, p, row, col);
  206.                 end;
  207.             end;
  208.         begin
  209.             if ch = tab then
  210.                 ch := spc;
  211.             if ch = del then
  212.                 ch := bs;
  213.             case ch of
  214.                 cr, lf: 
  215.                     DoCR;
  216.                 bs: 
  217.                     DoDel;
  218.                 spc..ff: 
  219.                     DoCh;
  220.                 otherwise
  221.                     ;
  222.             end;
  223.         end;
  224.  
  225.         procedure SendMove (ch: char);
  226.             function NumToStr (n: integer): str15;
  227.                 var
  228.                     s: str255;
  229.             begin
  230.                 NumToString(n, s);
  231.                 while length(s) < 3 do
  232.                     s := concat('0', s);
  233.                 NumToStr := s;
  234.             end;
  235.         begin
  236.             ger.event := ge_SendMessage;
  237.             ger.message := concat('C', NumToStr(ord(ch)));
  238.         end;
  239.  
  240.         procedure DoMove (s: str15);
  241.             function StrToNum (s: str15; off: integer): integer;
  242.                 var
  243.                     n: longInt;
  244.             begin
  245.                 StringToNum(copy(s, off, 3), n);
  246.                 StrToNum := n;
  247.             end;
  248.             var
  249.                 ch: char;
  250.         begin
  251.             if length(s) <> 4 then
  252.                 Fail('Message not 4 chars')
  253.             else if s[1] <> 'C' then
  254.                 Fail('Messsage doesn''t start with C')
  255.             else begin
  256.                 ch := chr(StrToNum(s, 2));
  257.                 DoChar(pt_Bottom, ch);
  258.             end;
  259.         end;
  260.  
  261.         procedure DoKey;
  262.         begin
  263.             DoChar(pt_top, chr(ger.int1));
  264.             SendMove(chr(ger.int1));
  265.         end;
  266.  
  267.         procedure GetRect (var fi: fontInfo; var rct: rect; var mid: integer);
  268.             var
  269.                 hdl: handle;
  270.         begin
  271.             with rct do begin
  272.                 hdl := GetResource('DITL', 128);
  273.                 if hdl = nil then begin
  274.                     Fail('GetResource DITL failed');
  275.                     SetRect(rct, 4, 4, 100, 100);
  276.                 end
  277.                 else
  278.                     BlockMove(ptr(longInt(hdl^) + 6), @rct, SizeOf(rect));
  279.                 TextFont(monaco);
  280.                 TextSize(9);
  281.                 GetFontInfo(fi);
  282.                 right := left + 2 * width + 2 * inset + CharWidth('a') * col_max;
  283.                 with fi do begin
  284.                     bottom := top + 3 * width + 4 * inset + row_max * (ascent + descent) * 2 + (row_max - 1) * leading * 2;
  285.                     mid := top + width + 2 * inset + row_max * (ascent + descent) + (row_max - 1) * leading;
  286.                 end;
  287.             end;
  288.         end;
  289.  
  290.         procedure InitGame;
  291.             var
  292.                 i: integer;
  293.                 rct: rect;
  294.                 hdl: handle;
  295.                 port: grafport;
  296.                 fi: FontInfo;
  297.                 mid: integer;
  298.         begin
  299.             ger.globals := nil;
  300.             gglobals := globalsPeek(ger.globals);
  301.             OpenPort(@port);
  302.             GetRect(fi, rct, mid);
  303.             ClosePort(@port);
  304.             with rct do begin
  305.                 ger.int1 := left + right; { figure out why :-}
  306.                 ger.int2 := top + bottom;
  307.             end;
  308.         end; {proc}
  309.  
  310.         procedure FinishGame;
  311.         begin
  312.             ger.globals := nil;
  313.         end;
  314.  
  315.         procedure CommonInit;
  316.             var
  317.                 k: integer;
  318.                 h: handle;
  319.                 rct: rect;
  320.         begin
  321.             GetRect(ggame^.fi, ggame^.item_rect, ggame^.mid_line);
  322.             GetDItem(gwindow, my_dialog_item, k, h, rct);
  323.             rct := ggame^.item_rect;
  324.             InsetRect(rct, -width, -width);
  325.             SetDItem(gwindow, my_dialog_item, k, handle(@DrawGame), rct);
  326.             SetWRefCon(gwindow, longInt(ghandle));
  327.             ggame^.globals := gglobals;
  328.         end;
  329.  
  330.         procedure UpdateControls;
  331.         begin
  332.         end;
  333.  
  334.         procedure RestartGame;
  335.             var
  336.                 r: integer;
  337.                 p: pieceType;
  338.         begin
  339.             for p := pt_Top to pt_Bottom do
  340.                 with ggame^.player[p] do begin
  341.                     for r := 1 to row_max do begin
  342. {$PUSH}
  343. {$R-}
  344.                         lines[r][0] := chr(col_max);
  345. {$POP}
  346.                         ClearRow(p, r);
  347.                     end;
  348.                     row := 1;
  349.                     col := 1;
  350.                     lines[1][1] := cursor;
  351.                     DrawChr(ggame, p, row, col);
  352.                 end;
  353.             SetMyTurn;
  354.             UpdateControls;
  355.         end;
  356.  
  357.         procedure GameNew;
  358.         begin
  359.             HUnlock(ghandle);
  360.             SetHandleSize(ghandle, SizeOf(gameRecord));
  361.             HLock(ghandle);
  362.             ggame := gamePeek(ghandle^);
  363.             CommonInit;
  364.             with ggame^ do begin
  365.                 connectionstate := cs_Local;
  366.             end; {with}
  367.             RestartGame;
  368.         end;
  369.  
  370.         procedure OldGame;
  371.         begin
  372.             CommonInit;
  373.             ggame^.connectionstate := cs_Local;
  374.             SetMyTurn;
  375.             UpdateControls;
  376.         end;
  377.  
  378.         procedure InvalPort;
  379.             var
  380.                 r: rect;
  381.         begin
  382.             r := ggame^.item_rect;
  383.             InsetRect(r, width, width);
  384.             EraseRect(r);
  385.             InvalRect(gwindow^.portRect);
  386.         end;
  387.  
  388.         procedure Swap;
  389.             var
  390.                 s: str255;
  391.                 r, k: integer;
  392.                 pl: playerRecord;
  393.         begin
  394.             with ggame^ do begin
  395.                 pl := player[pt_Top];
  396.                 player[pt_Top] := player[pt_Bottom];
  397.                 player[pt_Bottom] := pl;
  398.             end;
  399.             InvalPort;
  400.             SetMyTurn;
  401.             UpdateControls;
  402.         end;
  403.  
  404.         procedure ConnectionLost;
  405.         begin
  406.             with ggame^ do begin
  407.                 connectionstate := cs_Local;
  408.                 SetMyTurn;
  409.             end; {with}
  410.         end;
  411.  
  412.         procedure ConnectionMade;
  413.         begin
  414.             with ggame^ do begin
  415.                 connectionstate := cs_Remote;
  416.                 SetMyTurn;
  417.             end; {with}
  418.         end;
  419.  
  420.         procedure Restart;
  421.         begin
  422.             RestartGame;
  423.             InvalPort;
  424.         end;
  425.  
  426.         procedure MouseDown;
  427.         begin
  428.         end;
  429.  
  430.         procedure MessageReceived;
  431.             var
  432.                 tmpstr: str255;
  433.                 x: longint;
  434.                 seq: longint;
  435.                 i, j: integer;
  436.         begin
  437.             DoMove(ger.message);
  438.         end;
  439.  
  440.     begin
  441.         gglobals := globalsPeek(ger.globals);
  442.         ghandle := ger.game;
  443.         if ghandle <> nil then begin
  444.             HLock(ghandle);
  445.             ggame := gamePeek(ghandle^);
  446.         end;
  447.         GetPort(gwindow);
  448.         PenSize(width, width);
  449.         case ger.event of
  450.             ge_InitRuleBook: 
  451.                 InitGame;
  452.             ge_FinishRuleBook: 
  453.                 FinishGame;
  454.             ge_NewGame: 
  455.                 GameNew;
  456.             ge_OldGame: 
  457.                 OldGame;
  458.             ge_ConnectionLost: 
  459.                 ConnectionLost;
  460.             ge_ConnectionMade: 
  461.                 ConnectionMade;
  462.             ge_MessageReceived: 
  463.                 MessageReceived;
  464.             ge_MouseDown: 
  465.                 MouseDown;
  466.             ge_Swap: 
  467.                 Swap;
  468.             ge_Restart: 
  469.                 Restart;
  470.             ge_KeyDown: 
  471.                 DoKey;
  472.             otherwise
  473.         end;
  474.         PenNormal;
  475.         if ghandle <> nil then
  476.             HUnlock(ghandle);
  477.     end;
  478.  
  479. end.